package com.example.rabbitmq_common.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;

import javax.annotation.Resource;

/**
 * @ClassName DirectRabbitConfig
 * @Description TODO
 * @Author gql
 * @Date 2023/3/10 17:12
 **/
@Configuration
public class DirectRabbitConfig implements BeanPostProcessor,RabbitListenerConfigurer {

    @Resource
    private AmqpAdmin amqpAdmin;



    @Bean
    public Queue rabbitmqDirectQueue(){
        /**
         * 1.NAME 队列名称
         * 2.durable:是否持久化
         * 3.exclusive:exclusive: 是否独享、排外的。如果设置为true，定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
         * 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后，会自动删除。
        */
        return new Queue(RabbitMQConfigConstants.RABBITMQ_DEMO_TOPIC,true,false,false);
    }

    @Bean
    public DirectExchange rabbitmqDemoDirectExchange(){
        /**
         * 1.交换机名称
         * 2.是否持久化
         * 3.是否自动删除
         */
        return new DirectExchange(RabbitMQConfigConstants.DIRECT_EXCHANGE,true,false);
    }

    /**
     * 创建队列
     */

    @Bean(value = RabbitMQConfigConstants.RABBITMQ_DEMO_TOPIC)
    public void createQueue(){
        amqpAdmin.declareQueue(rabbitmqDirectQueue());
    }

    /**
     * 创建交换机
     */
    @Bean(value = RabbitMQConfigConstants.DIRECT_EXCHANGE)
    public void createExchange(){
        amqpAdmin.declareExchange(rabbitmqDemoDirectExchange());
    }


    @Bean
    public Binding bindDirect(){
        return BindingBuilder
                .bind(rabbitmqDirectQueue())
                .to(rabbitmqDemoDirectExchange())
                .with(RabbitMQConfigConstants.DIRECT_ROUTING);
    }

    @Bean
    public Queue rabbitmqDirectQueue2(){
        /**
         * 1.NAME 队列名称
         * 2.durable:是否持久化
         * 3.exclusive:exclusive: 是否独享、排外的。如果设置为true，定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
         * 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后，会自动删除。
         */
        return new Queue(RabbitMQConfigConstants.RABBITMQ_DEMO_TOPIC2,true,false,false);
    }

    @Bean
    public DirectExchange rabbitmqDemoDirectExchange2(){
        /**
         * 1.交换机名称
         * 2.是否持久化
         * 3.是否自动删除
         */
        return new DirectExchange(RabbitMQConfigConstants.DIRECT_EXCHANGE2,true,false);
    }

    /**
     * 创建队列
     */

    @Bean(value = RabbitMQConfigConstants.RABBITMQ_DEMO_TOPIC2)
    public void createQueue2(){
        amqpAdmin.declareQueue(rabbitmqDirectQueue2());
    }

    /**
     * 创建交换机
     */
    @Bean(value = RabbitMQConfigConstants.DIRECT_EXCHANGE2)
    public void createExchang2e(){
        amqpAdmin.declareExchange(rabbitmqDemoDirectExchange2());
    }


    @Bean
    public Binding bindDirec2t(){
        return BindingBuilder
                .bind(rabbitmqDirectQueue2())
                .to(rabbitmqDemoDirectExchange2())
                .with(RabbitMQConfigConstants.DIRECT_ROUTING2);
    }


    // 提供自定义RabbitTemplate,将对象序列化为json串
    @Bean
    public RabbitTemplate jacksonRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public DefaultMessageHandlerMethodFactory myHandlerMethodFactory(){
        DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
        // 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message body
        factory.setMessageConverter(new MappingJackson2MessageConverter());
        return factory;
    }

    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar rabbitListenerEndpointRegistrar) {
        rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
    }
}
